﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using Migration;
using Migration.Classes;
using Telerik.Sitefinity.Services.Migration;
using System.IO;
using System.Web;

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MigrationService : IMigrationService
{
	private MigrationModule m_MigrationModule;
	private const string m_FilePath = "~/App_Data/Sitefinity/Logs/Migration.log.htm";
	private const string m_CancelFilePath = "~/App_Data/Sitefinity/Logs/MigrationCancel.txt";

	private MigrationItemStatistics GetStatistics()
	{
		var mic = m_MigrationModule.GetContentStatistics();
		if (mic != null)
		{
			MigrationStatistics.RolesCount = mic.RolesCount;
			MigrationStatistics.UsersCount = mic.UsersCount;
			MigrationStatistics.ImageLibrariesCount = mic.ImageLibrariesCount;
			MigrationStatistics.DocumentLibrariesCount = mic.DocumentLibrariesCount;
			MigrationStatistics.VideoLibrariesCount = mic.VideoLibrariesCount;
			MigrationStatistics.GenericContentsCount = mic.GenericContentsCount;
			MigrationStatistics.NewsCount = mic.NewsCount;
			MigrationStatistics.BlogsCount = mic.BlogsCount;
			MigrationStatistics.BlogPostsCount = mic.BlogPostsCount;
			MigrationStatistics.EventsCount = mic.EventsCount;
			MigrationStatistics.ListsCount = mic.ListsCount;
			MigrationStatistics.MasterPagesCount = mic.MasterPagesCount;
			MigrationStatistics.ThemesCount = mic.ThemesCount;
			MigrationStatistics.TemplatesCount = mic.TemplatesCount;
			MigrationStatistics.PagesCount = mic.PagesCount;
		}

		return mic;
	}

	public MigrationItemStatistics GetMigrationCounts(string siteUrl)
	{
		m_MigrationModule = new MigrationModule();

		MigrationLogger.ClearLog();

		bool success = m_MigrationModule.CheckService(siteUrl);

		if (success)
		{
			var result = GetStatistics();

			MigrationLogger.AppendLogMessage("<b>Migration complete.</b>");

			return result;
		}
		else
		{
			MigrationLogger.AppendLogMessage("<b>Migration stopped.</b>");
		}

		return null;
	}

	public string MigrationStart(string siteUrl, string checkedBoxesToMigrate, string rolesProvider, string usersProvider, string librariesProvider, string genericContentsProvider, string newsProvider, string blogsProvider, string eventsProvider, string listsProvider, bool createContentBlocksOnErrors, bool rewriteRegisterTags)
	{
		m_MigrationModule = new MigrationModule();

		bool success = m_MigrationModule.CheckService(siteUrl);

		if (success)
		{
			// Create the available languages first
			var mic = GetStatistics();
			if (mic == null) return "FAIL";

            if (!MigrationCultures.AllCulturesPresent(mic.ContentLanguages))
            {
                MigrationLogger.AppendLogMessage("Some languages are not added in your 4.x project. Please make sure you have all of the following languages:<br/>");
                foreach (var contentLanguage in mic.ContentLanguages)
                {
                    MigrationLogger.AppendLogMessage(String.Format("<b>{0}</b>, ({1})<br/>", new System.Globalization.CultureInfo(contentLanguage).EnglishName, contentLanguage));
                }

                return "SUCCESS";
            }

			MigrationSettings.RolesProvider = rolesProvider;
			MigrationSettings.UsersProvider = usersProvider;
			MigrationSettings.LibrariesProvider = librariesProvider;
			MigrationSettings.GenericContentProvider = genericContentsProvider;
			MigrationSettings.NewsProvider = newsProvider;
			MigrationSettings.BlogsProvider = blogsProvider;
			MigrationSettings.EventsProvider = eventsProvider;
			MigrationSettings.ListsProvider = listsProvider;
			MigrationSettings.CreateContentBlocksOnErrors = createContentBlocksOnErrors;
			MigrationSettings.RewriteRegisterTags = rewriteRegisterTags;
			MigrationSettings.MigrationCancelled = false;

			var split = checkedBoxesToMigrate.Split(",".ToCharArray());

			for (int i = 0; i < split.Length; i++)
			{
				if (!String.IsNullOrEmpty(split[i]) && !MigrationSettings.MigrationCancelled)
					m_MigrationModule.DoMigration(siteUrl, split[i]);
			}

			if (!MigrationSettings.MigrationCancelled)
			{
				m_MigrationModule.EndMigration();

				MigrationLogger.AppendLogMessage("<br/><b>Migration complete.</b>");
			}

			return "SUCCESS";
		}
		else
		{
			MigrationLogger.AppendLogMessage("<br/><b>Migration stopped.</b>");

			return "FAIL";
		}
	}

	public void ClearLog()
	{
		// Clear the log file and delete the cancel indicator flag
		var resolvedPath = HttpContext.Current.Server.MapPath(m_FilePath);

		if (File.Exists(resolvedPath))
		{
			try
			{
				using (StreamWriter sw = new StreamWriter(resolvedPath))
				{
					sw.Write(String.Empty);
				}
			}
			catch (IOException) { }
		}

		resolvedPath = HttpContext.Current.Server.MapPath(m_CancelFilePath);

		if (File.Exists(resolvedPath))
		{
			try
			{
				File.Delete(resolvedPath);
			}
			catch (IOException) { }
		}
	}

	public string GetLog()
	{
		var resolvedPath = HttpContext.Current.Server.MapPath(m_FilePath);
		var result = String.Empty;

		if (File.Exists(resolvedPath))
		{
			// Don't lock the file when reading it
			var fs = new FileStream(resolvedPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
			var sr = new StreamReader(fs);
			result = sr.ReadToEnd();
			sr.Close();
		}

		if (MigrationSettings.MigrationCancelled)
			result = "CANCELLED" + result;

		return result;
	}

	public void CancelMigration()
	{
		var resolvedPath = HttpContext.Current.Server.MapPath(m_CancelFilePath);

		if (!File.Exists(resolvedPath))
		{
			try
			{
				using (var sw = new StreamWriter(resolvedPath))
				{
					sw.Write("CANCELLED");
				}
			}
			catch (IOException) { }
		}
	}
}
